﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

// This is a cell in the maze
public class MazeCell : MonoBehaviour {
	// The location of the cell
	public IntVector2 coordinates;
	// The edges of this cell
	public MazeCellEdge[] edges = new MazeCellEdge[MazeDirections.count];
	// Keeps track of how many edges each cell has during generation
	private int initializedEdgeCount = 0;
	// Does this cell have the enemy?
	public bool hasEnemy = false;
	// The maze
	public Maze maze;

	// Runs on start up.
	void Start() {
		maze = GameObject.Find ("Maze(Clone)").GetComponent<Maze> ();
	}

	// Return a specific edge based on the direction.
	public MazeCellEdge GetEdge (MazeDirection direction) {
		return edges[(int)direction];
	}

	// Set an edge in the direction specified.
	public void SetEdge (MazeDirection direction, MazeCellEdge edge) {
		edges [(int)direction] = edge;
		initializedEdgeCount += 1;
	}

	// Is this cell initialized completely?
	public bool IsFullyInitialized {
		get {
			return initializedEdgeCount == MazeDirections.count;
		}
	}

	// Picks a random direction that has yet to be initialized.
	public MazeDirection RandomUninitializedDirection {
		get {
			int skips = Random.Range(0, MazeDirections.count - initializedEdgeCount);
			for(int i = 0; i < MazeDirections.count; i++) {
				if(edges[i] == null) {
					if(skips == 0) {
						return (MazeDirection)i;
					}
					skips -= 1;
				}
			}
			throw new System.InvalidOperationException("MazeCell has no uninitialized directions left.");
		}
	}

	// If the enemy steps into this tile, it's here.
	void OnTriggerEnter2D(Collider2D other) {
		if (other.tag.Equals ("Enemy")) {
			hasEnemy = true;
		}
	}

	// Paint the tile the color of the player/enemy.
	void OnTriggerStay2D(Collider2D other) {
		SpriteRenderer rend = GetComponent<SpriteRenderer> ();
		if (other.tag.Equals ("Player") && !rend.color.Equals (new Color(1, .67f, .67f))) {
			if(rend.color != Color.white) {
				maze.enemyCount(-1);
			}
			maze.playerCount(1);
			rend.color = new Color(1, .67f, .67f);
		}
		if (other.tag.Equals ("Enemy") && !rend.color.Equals (new Color(.64f, .38f, .57f))) {
			if(rend.color != Color.white) {
				maze.playerCount(-1);
			}
			maze.enemyCount(1);
			rend.color = new Color(.64f, .38f, .57f);
		}
	}

	// If the enemy leaves this tile, it's not here.
	void OnTriggerExit2D(Collider2D other) {
		if (other.tag.Equals ("Enemy")) {
			hasEnemy = false;
		}
	}

	// Return the passages available at this cell.
	public MazeCellEdge[] passages() {
		List<MazeCellEdge> arr = new List<MazeCellEdge>();
		foreach (MazeCellEdge edge in edges) {
			if(!edge.isWall()) {
				arr.Add(edge);
			}
		}
		//print ("Maze name is: " + name);
		//print ("Number of Passages: " + arr.Count);
		return arr.ToArray();
	}

	// Given a passage of this cell, return the other cell connected to this one by that passage.
	public MazeCell getOtherCell(MazeCellEdge pass) {
		MazeCell[] cells = pass.cells();
		if (cells[0].Equals(this)) {
			return cells[1];
		} else {
			return cells[0];
		}
	}

	// Check if the given object is the same as this cell by checking their coordinates.
	public override bool Equals(object obj) {
		MazeCell other = (MazeCell)obj;
		return other.coordinates.Equals (coordinates);
	}

	// Get the hashcode.
	public override int GetHashCode ()
	{
		return base.GetHashCode ();
	}

}
